#!/usr/bin/env python
# encoding: utf-8

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from ui.mqttClient import Ui_MainWindow
import paho.mqtt.client as mqtt

class Mqtt:
    def __init__(self):
        pass
        # mqtt配置
        # self.configfile = os.getcwd()+'/conf/mqtt.conf'
        # config = configparser.ConfigParser()
        # config.read(self.configfile)
        # mqtt = config['mqtt']
        # 配置设置
        self.client = None

    def client_loop(self, host='', port='', client_id='', admin='',password=''):
        self.client = mqtt.Client(client_id)  # ClientId不能重复，所以使用当前时间
        self.client.username_pw_set(admin, password)  # 必须设置，否则会返回「Connected with result code 4」
        self.client.on_connect = self.on_connect
        self.client.on_message = self.on_message
        try:
            self.client.connect(host, int(port), 60)
            self.client.loop_forever()
        except Exception as e:
            print(e)

    def on_connect(self, client, userdata, flags, rc):
        """客户端订阅消息
        多个主题订阅：
            [("topic1", qos), ("topic2", qos)]
        单个主题订阅: "topic1", qos
        """
        print("Connected with result code " + str(rc))
        #  logging.info("Connected with result code " + str(rc))
        # topic_list = self.sub_topic.split(';')
        # topic_list = [(topic_list[i], 0) for i in range(0, len(topic_list)) if topic_list[i]]
        # nodes = self.nodes.nodes
        # topic = ["topic1"]
        # if nodes:
            # for n in nodes:
                # topic.append((n['cid'],1))
        self.client.subscribe("17740171896",qos=0)
        print("Subscribe List：", topic)
        # self.on_publish_more("%s:online"%self.equ_uuid)

    def on_publish(self, topic, payload, qos=0):
        """客户端推送消息

        topic: 推送主题
        payload: 推送内容/负载
        qos: 服务质量等级，
            qos0:发送者只发送一次消息，不进行重试，Broker不会返回确认消息
            qos1:发送者最少发送一次消息，确保消息到达Broker，Broker需要返回确认消息PUBACK
            qos2(相比qos1开销很大):使用两阶段确认来保证消息的不丢失和不重复
        """
        print('MQTT Publish : [%s] %s' % (topic, payload))
        logging.info('MQTT Publish : [%s] %s' % (topic, payload))
        self.client.publish(topic, payload, qos)

    def on_message(self, client, userdata, msg):
        """客户端接收订阅的消息

        client: 客户端
        userdata: 用户数据
        msg: 接收数据
            msg.topic: 接收消息的主题名称
            msg.pyload: 接收到消息的内容/负载
        """
        topic = str(msg.topic)
        message = str(msg.payload.decode("utf-8"))
        pyload = msg.payload
        # print(msg.clientID)
        print('-'*20+"MQTT接收："+'-'*20)
        print("MQTT Recv:\r\n\ttopic:{topic}\r\n\tmsg:{msg}".format(topic=topic, msg=message))
        #  logging.info("MQTT Recv:\r\n\ttopic:{topic}\r\n\tmsg:{msg}".format(topic=topic, msg=message))

    def ser_send(self, lora_addr='', target='',local='',_type='',cmd='',content=''):
        header = 'AA'
        data = target+local+_type+cmd+content
        length = hex(int(len(data)/2)).replace('0x','').zfill(2)[-2:]
        if len(data)>0 and len(data) % 2 == 0:
            data_list = [int(data[i:i+2], 16) for i in range(0,len(data)) if i%2==0]
            _sum = hex(sum(data_list) % 256).replace('0x','').zfill(2)[-2:]
            cmd = lora_addr+header+length+data+_sum
            print(cmd)
            try:
                self.ser.write(cmd.upper(), 'hex')
            except Exception as e:
                print(e)

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.lineEdit_host.setText('localhost')
        self.lineEdit_port.setText('1883')
        self.pushButton_connect.clicked.connect(self.connect)
        self.mqtt = Mqtt()

    def connect(self):
        self.mqtt.client_loop(
            host     = self.lineEdit_host.text(),
            port     = self.lineEdit_port.text(),
            client_id= self.lineEdit_clientID.text(),
        )

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    app.exec_()

